package Parser;


import java.io.*;
import java.util.*;

public class LexStream {

    BufferedReader read;
    int buffer;

    StringBuffer token;
    ArrayList tokens = new ArrayList();


    /*
      Tags:
        table
        row
        col

        img
        div
        p
        br
     */

    public LexStream(BufferedReader read) {
        this.read = read;
        buffer = -1;
    }

    // Leaves the body tag in the token
    public void gotoBody() throws Exception {
        if (token == null)
          nextToken();

        while (token != null && token.length() >= 5 &&
               !token.substring(0, 5).toLowerCase().equals("<body"))
            nextToken();
    }

    public String getToken() {
        return token.toString();
    }

    public boolean hasToken()
    {
        return (token != null);
    }

    public void nextToken() throws Exception
    {
      if (tokens.size() > 0)
      {
          token = new StringBuffer((String)tokens.remove(0));
      }
      else
      {
          findToken();
      }
    }

    public void findToken() throws Exception {
        char cur;
        boolean stop;

        if (buffer == -1) {
            buffer = read.read();
        }

        // EOF
        if (buffer == -1) {
            token = null;
            return;
        }

        cur = (char) buffer;

        // Trim any white space
        while (isWhiteSpace(cur))
        {
            buffer = read.read();
            // EOF
            if (buffer == -1) {
                token = null;
                return;
            }
            cur = (char) buffer;
        }

        if (cur == '<') {
            // Tag start, read to closing
            // unless it is a script tag, at which point we need
            // to read until the close script tag
            token = new StringBuffer();
            while (cur != '>' && buffer != -1 && token.length() < 7) {
                token.append(cur);
                buffer = read.read();
                cur = (char) buffer;
            }
            
            // Check for a script tag
            if (cur != '>' && buffer != -1) {
                if (token.toString().toLowerCase().equals("<script") && (cur == ' ' || cur == '>'))
                {
                    // It is a script, read until the end of script
                    // Which is necessarily </script>, IE nor Firefox allow
                    // var s = "</script>", it terminates the script tag
                    stop = false;
                    while (!stop && buffer != -1) {
                        token.append(cur);
                        buffer = read.read();
                        cur = (char) buffer;
                        
                        if (token.toString().toLowerCase().indexOf("</script", token.length() - 8) >= 0)
                          stop = true;                        
                    }
                }
                else {
                    // It is not a script tag, process normally
                    while (cur != '>' && buffer != -1) {
                        token.append(cur);
                        buffer = read.read();
                        cur = (char) buffer;
                    }
                }
            }
            
            token.append(cur);
            buffer = read.read();
            cur = (char) buffer;
        }
        else {
            token = new StringBuffer();
            // Not a tag, read until a tag or eof
            while (cur != '<' && buffer != -1) {
		token.append(cur);
		buffer = read.read();
                cur = (char) buffer;
            }

            // Handle HTML White space
            //compressWhiteSpace(token);
            token = new StringBuffer(token.toString().replaceAll("&nbsp;", " "));

            // Handle & chars
            token = new StringBuffer(token.toString().replaceAll("&amp;", "&"));

            // Fracture it based on breaks
            int pos = 0;
            int start = 0;
            String chunk = "";
            while (pos < token.length())
            {
              start = pos;
              while (pos < token.length() && !isWhiteSpace(token.charAt(pos))){
                pos++;
              }
              while (pos < token.length() && isWhiteSpace(token.charAt(pos))){
                pos++;
              }
              tokens.add(token.substring(start, pos));
              chunk = "";
            }

            token = new StringBuffer(tokens.remove(0).toString());
        }
    }

    public void compressWhiteSpace(StringBuffer t)
    {
        for (int c = 0; c < t.length(); c++)
        {
            if (isWhiteSpace(t.charAt(c)))
            {
                if (t.charAt(c - 1) == ' ')
                  t.deleteCharAt(c);
            }
        }
    }

    public boolean isWhiteSpace(char c)
    {
        return Character.isWhitespace(c);
    }

}
